//
//  PSBid.h
//  PrefCore
//
//  Created by Sergey on 1/16/14.
//  Copyright (c) 2014 Play-on-smart. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "PSCard.h"

/// Represents the type of a card bid.
typedef enum {
    kBidNone
,   kBidPlay
,   kBidMisere
,   kBidPass
,   kBidWithoutThree
,   kBidWhist
,   kBidHalfWhist
,   kBidCheckTen
} PSBidType;

/// Represents the count of tricks.
typedef uint8_t PSTrickCount;

/// The smallest number of tricks required to start bidding.
#define PS_BID_MIN ((PSTrickCount)6)

/// The highest number of tricks in a bidding.
#define PS_BID_MAX ((PSTrickCount)10)

/// Determines the index of a contract based on the number of tricks.
/// @param tricks The number of tricks in the contract.
/// @return The index of the corresponding contract.
extern uint8_t PSGetContractIndex(PSTrickCount tricks);

/// Represents a bid in a game. Instances of this class are immutable.
@interface PSBid : NSObject

/// Makes a bid with the specific trump and a number of tricks.
/// @param trump The trump of this contract.
/// @param tricks The number of tricks required by this contract.
+(instancetype)bidPlayWithTrump:(PSCardSuit)trump tricks:(PSTrickCount)tricks;

/// Represents a bid of "misere".
+(instancetype)bidMisere;

/// Represents a bid of ending the game with the penalty of less than three tricks.
+(instancetype)bidWithoutThree;

/// Represents a passing bid.
+(instancetype)bidPass;

/// Represents a bid of whist.
+(instancetype)bidWhist;

/// Represents a bid of half whist.
+(instancetype)bidHalfWhist;

/// Represents a bid of ten tricks, which needs to be checked, not played.
+(instancetype)bidCheckTen;

/// Represents an absence of the bid;
+(instancetype)bidNone;

/// The type of this bid.
@property (nonatomic, readonly) PSBidType type;

/// If the bid is a play contract, this is the number of tricks.
@property (nonatomic, readonly) PSTrickCount tricks;

/// If the bid is a play contract, this is the trump suit.
@property (nonatomic, readonly) PSCardSuit trump;

/// YES if this is a play contract; NO otherwise.
-(BOOL)isPlay;

/// YES if this is a misere contract; NO otherwise.
-(BOOL)isMisere;

/// YES if this is a pass contract; NO otherwise.
-(BOOL)isPass;

/// YES if this is a half-whist contract; NO otherwise.
-(BOOL)isHalfWhist;

/// YES if this is a whist contract; NO otherwise.
-(BOOL)isWhist;

/// YES if this is a without-three contract; NO otherwise.
-(BOOL)isWihoutThree;

/// YES if this is a check ten contract; NO otherwise.
-(BOOL)isCheckTen;

/// Determines if a given bid is greater than this one.
/// @param other The other bid to compare to the current one.
/// @return YES if this bid is greater than the other one; NO otherwise.
-(BOOL)isGreaterThanBid:(PSBid*)other;

/// Finds the next higher bid after the current one.
-(PSBid*)nextBid;

/// Returns a bid with the same trump and the number of tricks
/// that is greater by one than the current bid.
-(PSBid*)incrementTricks;

/// Determines if the number of tricks in this contract can go up
/// without making the contract illegal.
-(BOOL)canIncrementTricks;

/// Returns a bid with the same trump and the number of tricks
/// that is smaller by one than the current bid.
-(PSBid*)decrementTricks;

/// Determines if the number of tricks in this contract can go down
/// without making the contract illegal.
-(BOOL)canDecrementTricks;

@end
